﻿#include "hashmap.h"

// 哈希函数
unsigned int hash(const char* key) {
    unsigned int hash = 0;
    for (int i = 0; key[i] != '\0'; i++) {
        hash = (hash * 31 + (unsigned int)key[i]) % TABLE_SIZE;
    }
    return hash;
}

// 初始化哈希表
void init_hash_map(HashMap* map) {
    for (int i = 0; i < TABLE_SIZE; i++) {
        map->buckets[i] = NULL;
        pthread_mutex_init(&map->locks[i], NULL);
    }
}

// 插入或更新键值对
void insert_or_update(HashMap* map, const char* key, void* value) {
    unsigned int index = hash(key);
    pthread_mutex_lock(&map->locks[index]);
    Node* current = map->buckets[index];
    Node* prev = NULL;

    while (current != NULL) {
        if (strcmp(current->key, key) == 0) {
            current->value = value;  // 更新值
            return;
        }
        prev = current;
        current = current->next;
    }

    Node* new_node = (Node*)malloc(sizeof(Node));
    if (new_node == NULL) {
        perror("Memory allocation failed");
        exit(EXIT_FAILURE);
    }
    strcpy(new_node->key, key);
    new_node->value = value;  // 存储 void * 指针
    new_node->next = NULL;

    if (prev == NULL) {
        map->buckets[index] = new_node;
    }
    else {
        prev->next = new_node;
    }
    pthread_mutex_unlock(&map->locks[index]);
}

// 查找键值对
void* find(HashMap* map, const char* key) {
    unsigned int index = hash(key);
    Node* current = map->buckets[index];

    while (current != NULL) {
        if (strcmp(current->key, key) == 0) {
            return current->value;
        }
        current = current->next;
    }
    return NULL;  // 键不存在
}

// 删除键值对
void hash_delete(HashMap* map, const char* key) {
    unsigned int index = hash(key);
    Node* current = map->buckets[index];
    Node* prev = NULL;
    pthread_mutex_lock(&map->locks[index]);

    while (current != NULL) {
        if (strcmp(current->key, key) == 0) {
            if (prev == NULL) {
                map->buckets[index] = current->next;
            }
            else {
                prev->next = current->next;
            }
            free(current);  // 释放 Node 结构本身，但不释放 value 指针
            pthread_mutex_unlock(&map->locks[index]);
            return;
        }
        prev = current;
        current = current->next;
    }
    pthread_mutex_unlock(&map->locks[index]);
}


// 释放哈希表内存
void free_hash_map(HashMap* map) {
    for (int i = 0; i < TABLE_SIZE; i++) {
        Node* current = map->buckets[i];
        while (current != NULL) {
            Node* temp = current;
            current = current->next;
            free(temp);  // 释放 Node 结构本身，但不释放 value 指针
        }
    }
}